/*
 * (c) 2007, Delsi Interactive
 * User: ChRoNo
 * Date: 16/04/2007
 * Time: 09:44 p.m.
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace CSE
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		/*
		 * Constants
		 */
		public static readonly int DRAG_NONE = 0;
		public static readonly int DRAG_ALL = 1;
		public static readonly int DRAG_LEFT = 2;
		public static readonly int DRAG_RIGHT = 3;
		public static readonly int DRAG_UP = 4;
		public static readonly int DRAG_DOWN = 5;
		public static readonly int DRAG_STAGE = 6;
		
	    /*
	     * Variables
	     */
	    public static MainForm self = null;
	    public static NewClip nc = null;
	    public static GetClips gc = null;
	    
	    public static TreeView TreeView = null;
	    public static TreeNodeCollection libAbs = null;
	    public static TreeNode libClipsRoot = null;
	    public static TreeNode libClipsLibrary = null;
	    public static TreeNode libBitmap = null;
	    public static TreeNode libSel = null;
	    public static TreeNode libEdit = null;
	    
	    private int DragType = DRAG_NONE;
	    private int DragOX = 0;
	    private int DragOY = 0;
	    private int DragTemp = 0;
	    
	    [STAThread]
		public static void Main(string[] args)
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Application.Run(new MainForm());
		}
		
		public MainForm()
		{
			InitializeComponent();
			self = this;
			TreeView = this.treeLibrary;
			this.DoubleBuffered = true;
			
			MainFormSetDefaults();
		}
		
		/*
		 * MainFormLoad
		 */
		void MainFormLoad(object sender, EventArgs e)
		{
			this.spriteToolStripMenuItem.Visible = false;
		}
		
		/*
		 * MainFormResize
		 */
		void MainFormResize(object sender, EventArgs e)
		{
			this.picStage.Invalidate();
		}
		
		/*
		 * MainFormSetDefaults
		 */
		public void MainFormSetDefaults ()
		{
			this.cboZoom.Text = "100%";
			this.tipPos.Text = "";
			PropertiesShow(false);
			
			this.lblClipName.Text = Workspace.CLIP_NAME_NONAME;
			
			libSel = null;
			libEdit = null;
			
			if (Workspace.type == Workspace.TYPE_SPRITE)
			{
				this.spriteToolStripMenuItem.Visible = true;
				
				this.cboZoom.Enabled = true;
				this.tcStage.Enabled = false;
				
				CreateSpriteLibrary();
			}
			else
			{
				this.cboZoom.Enabled = false;
				this.tcStage.Enabled = false;
			}
		}
		
		/*
		 * PropertiesShow
		 */
		void PropertiesShow (bool sw)
		{
		    if (!sw)
		    {
		        this.txtPropName.Text = "";
		        this.txtX.Text = "";
			    this.txtY.Text = "";
			    this.txtW.Text = "";
			    this.txtH.Text = "";
		    }
		    
		    this.txtPropName.Visible = sw;
		    this.lblName.Visible = sw;
		    
		    this.txtX.Visible = sw;
		    this.txtY.Visible = sw;
		    this.txtW.Visible = sw;
		    this.txtH.Visible = sw;
		    
		    this.lblX.Visible = sw;
		    this.lblY.Visible = sw;
		    this.lblW.Visible = sw;
		    this.lblH.Visible = sw;
		}
		
		/*
		 * CreateSpriteLibrary
		 */
		private void CreateSpriteLibrary ()
		{
			ImageList myImageList = new ImageList();
			myImageList.Images.Add(Utils.LoadBitmapResource("clip.Bitmap"));
			myImageList.Images.Add(Utils.LoadBitmapResource("animclip.Bitmap"));
		    myImageList.Images.Add(Utils.LoadBitmapResource("bitmap.Bitmap"));
		    myImageList.Images.Add(Utils.LoadBitmapResource("folder.Bitmap"));
		    
		    this.treeLibrary.ImageList = myImageList;
		    this.treeLibrary.ImageIndex = 0;
		    
		    libAbs = this.treeLibrary.Nodes;
		    
		    libClipsRoot = this.treeLibrary.Nodes.Add(Workspace.GetKey().ToString() + "_clip", "_root", 1, 1);
		    libClipsLibrary = this.treeLibrary.Nodes.Add(Workspace.GetKey().ToString() + "_library", "Library", 3, 3);
		    libBitmap = this.treeLibrary.Nodes.Add("_bitmap", "Bitmap", 2, 2);
		    
		    libBitmap.Nodes.Add("_bitmap_source", "(null)", 2, 2);
		}
		
		/*
		 * File/New
		 */
		void NewToolStripMenuItemClick(object sender, EventArgs e)
		{
		    Workspace.Shutdown();
		    Workspace.Init();
		    
		    this.picStage.Invalidate();
		}
		
		/*
		 * File/Load
		 */
		void LoadToolStripMenuItemClick(object sender, EventArgs e)
		{
			OpenFileDialog ofdSprite = new OpenFileDialog();
            ofdSprite.Filter = "Sprite Files |*.cse";
            ofdSprite.Multiselect = false;
            
            if (ofdSprite.ShowDialog() == DialogResult.OK)
            {
            	Workspace.Shutdown();
            	Workspace.Init();
            	Workspace.SetPath(ofdSprite.FileName.Substring(0,ofdSprite.FileName.LastIndexOf('\\') + 1));
            	Workspace.Load(ofdSprite.FileName);
            	this.picStage.Invalidate();
            }
		}
		
		/*
		 * File/Save
		 */
		void SaveToolStripMenuItemClick(object sender, EventArgs e)
		{
			SaveFileDialog sfdSprite = new SaveFileDialog();
            sfdSprite.Filter = "Sprite Files |*.cse";
            
            if (sfdSprite.ShowDialog() == DialogResult.OK)
            {
                Workspace.SetPath(sfdSprite.FileName.Substring(0,sfdSprite.FileName.LastIndexOf('\\') + 1));
            	Workspace.Save(sfdSprite.FileName);
            	this.picStage.Invalidate();
            }
		}
		
		/*
		 * File/Export/Sprite (XML)
		 */
		void SpriteXMLToolStripMenuItemClick(object sender, EventArgs e)
		{
			SaveFileDialog sfdSprite = new SaveFileDialog();
            sfdSprite.Filter = "XML Files |*.xml";
            
            if (sfdSprite.ShowDialog() == DialogResult.OK)
            {
            	Workspace.ExportXML(sfdSprite.FileName);
            }
		}
		
		/*
		 * File/Preferences
		 */
		void PreferencesToolStripMenuItemClick(object sender, EventArgs e)
		{
			
		}

		/*
		 * Sprite/Get clips
		 */
		void GetClipsToolStripMenuItemClick(object sender, EventArgs e)
		{
			gc = new GetClips();
		}

		/*
		 * Sprite/Set source image
		 */
		void SetSourceImageToolStripMenuItemClick(object sender, EventArgs e)
		{
			OpenFileDialog ofdSprite = new OpenFileDialog();
            ofdSprite.Filter = "PNG Image Files |*.png";
            ofdSprite.Multiselect = false;
            
            if (ofdSprite.ShowDialog() == DialogResult.OK)
            {
                Workspace.SetPath(ofdSprite.FileName.Substring(0,ofdSprite.FileName.LastIndexOf('\\') + 1));
                Workspace.SetSourceBitmap(ofdSprite.FileName.Substring(ofdSprite.FileName.LastIndexOf('\\') + 1));
            	libBitmap.Nodes.Clear();
            	libBitmap.Nodes.Add("_bitmap_source", Workspace.bitmap_path, 2, 2);
            }
		}
		
		/*
		 * PicStagePaint
		 */
		void PicStagePaint(object sender, PaintEventArgs e)
		{
		    Stage.Draw(e.Graphics, this.picStage.Width, this.picStage.Height);
		}
		
		/*
		 * PicStageMouseDown
		 */
		void PicStageMouseDown (object sender, MouseEventArgs e)
		{
			DragType = DRAG_NONE;
			this.picStage.Cursor = System.Windows.Forms.Cursors.Default;
			int x = Stage.GetPixelsX(e.X, this.picStage.Width);
			int y = Stage.GetPixelsY(e.Y, this.picStage.Height);
			
			if (e.Button == MouseButtons.Left)
			{
    			if (libEdit == null)
    			{
    				return;
    			}
    			
    			Rectangle r_center = new Rectangle(((Clip)libEdit.Tag).r.X + 2,
    			                            ((Clip)libEdit.Tag).r.Y + 2,
    			                            ((Clip)libEdit.Tag).r.Width - 3,
    			                            ((Clip)libEdit.Tag).r.Height - 3);
    			
    			Rectangle r_left = new Rectangle(((Clip)libEdit.Tag).r.X - 1,
    			                            ((Clip)libEdit.Tag).r.Y - 1,
    			                            3,
    			                            ((Clip)libEdit.Tag).r.Height + 2);
    			
    			Rectangle r_right = new Rectangle((((Clip)libEdit.Tag).r.X + ((Clip)libEdit.Tag).r.Width ) - 1,
    			                            ((Clip)libEdit.Tag).r.Y - 1,
    			                            3,
    			                            ((Clip)libEdit.Tag).r.Height + 2);
    			
    			Rectangle r_up = new Rectangle(((Clip)libEdit.Tag).r.X - 1,
    			                            ((Clip)libEdit.Tag).r.Y - 1,
    			                            ((Clip)libEdit.Tag).r.Width + 2,
    			                            3);
    			
    			Rectangle r_down = new Rectangle(((Clip)libEdit.Tag).r.X - 1,
    			                            (((Clip)libEdit.Tag).r.Y + ((Clip)libEdit.Tag).r.Height) - 1,
    			                            ((Clip)libEdit.Tag).r.Width + 2,
    			                            3);
    			
    			if (r_center.Contains(x, y))
    			{
    				DragType = DRAG_ALL;
    				DragOX = x - (((Clip)libEdit.Tag).r.X);
    				DragOY = y - (((Clip)libEdit.Tag).r.Y);
    				this.picStage.Cursor = System.Windows.Forms.Cursors.NoMove2D;
    			}
    			else if (r_left.Contains(x, y))
    			{
    				DragType = DRAG_LEFT;
    				DragOX = x;
    				DragTemp = ((Clip)libEdit.Tag).r.Width;
    				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeWE;
    			}
    			else if (r_right.Contains(x, y))
    			{
    				DragType = DRAG_RIGHT;
    				DragOX = x;
    				DragTemp = ((Clip)libEdit.Tag).r.Width;
    				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeWE;
    			}
    			else if (r_up.Contains(x, y))
    			{
    				DragType = DRAG_UP;
    				DragOY = y;
    				DragTemp = ((Clip)libEdit.Tag).r.Height;
    				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeNS;
    			}
    			else if (r_down.Contains(x, y))
    			{
    				DragType = DRAG_DOWN;
    				DragOY = y;
    				DragTemp = ((Clip)libEdit.Tag).r.Height;
    				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeNS;
    			}
			}
			else if (e.Button == MouseButtons.Right)
			{
			    DragType = DRAG_STAGE;
			    DragOX = e.X;
			    DragOY = e.Y;
			}
		}
		
		/*
		 * PicStageMouseMove
		 */
		void PicStageMouseMove (object sender, MouseEventArgs e)
		{
			if (Workspace.type == Workspace.TYPE_NONE)
			{
				return;
			}
			
			int x = Stage.GetPixelsX(e.X, this.picStage.Width);
			int y = Stage.GetPixelsY(e.Y, this.picStage.Height);
			
			/*
			 * To prevent the modification of properties
			 */
			if (!this.picStage.Focused)
			{
			    this.picStage.Focus();
			}

			/*
			 * Show our position
			 */
			this.tipPos.Text = "x: " + x + " y: " + y;
			
			if (e.Button == MouseButtons.Left)
			{
    			if (libEdit == null)
    			{
    				return;
    			}
    
    			if (DragType == DRAG_ALL)
    			{
    				((Clip)libEdit.Tag).r.X = x - DragOX;
    				((Clip)libEdit.Tag).r.Y = y - DragOY;
    			}
    			else if (DragType == DRAG_LEFT)
    			{
    				int dx = x - DragOX;
    				((Clip)libEdit.Tag).r.X = x;
    				((Clip)libEdit.Tag).r.Width = DragTemp - dx;
    			}
    			else if (DragType == DRAG_RIGHT)
    			{
    				int dx = x - DragOX;
    				((Clip)libEdit.Tag).r.Width = DragTemp + dx;
    			}
    			else if (DragType == DRAG_UP)
    			{
    				int dy = y - DragOY;
    				((Clip)libEdit.Tag).r.Y = y;
    				((Clip)libEdit.Tag).r.Height = DragTemp - dy;
    			}
    			else if (DragType == DRAG_DOWN)
    			{
    				int dy = y - DragOY;
    				((Clip)libEdit.Tag).r.Height = DragTemp + dy;
    			}
			}
			else if (e.Button == MouseButtons.Right)
			{
			    if (DragType == DRAG_STAGE)
			    {
			        int dx = e.X - DragOX;
			        int dy = e.Y - DragOY;
			        
			        if (Math.Abs(dx) > Stage.SHIFT_ORIGIN) Stage.ox += (Utils.Sign(dx) * Stage.SHIFT_ORIGIN);
			        if (Math.Abs(dy) > Stage.SHIFT_ORIGIN) Stage.oy += (Utils.Sign(dy) * Stage.SHIFT_ORIGIN);
			        
			        DragOX = e.X;
			        DragOY = e.Y;
			    }
			}
			
			if (DragType != DRAG_NONE)
			{
				this.picStage.Invalidate();
			}
		}
		
		/*
		 * PicStageMouseUp
		 */
		void PicStageMouseUp (object sender, MouseEventArgs e)
		{
			DragType = DRAG_NONE;
			this.picStage.Cursor = System.Windows.Forms.Cursors.Default;
			
			if (libEdit == null)
			{
				return;
			}
		}
		
		/*
		 * Library Click
		 */
		void TreeLibraryAfterSelect(object sender, TreeViewEventArgs e)
		{
			string strkey = e.Node.Name.ToString();
			
			if (strkey.IndexOf("_clip") != -1)
			{
				e.Node.ContextMenuStrip = this.contextLibrary_clip;
			}
			else if (strkey.IndexOf("_library") != -1)
			{
				e.Node.ContextMenuStrip = this.contextLibrary_lib;
			}
			
			if (strkey.IndexOf("_bitmap_source") != -1)
			{
				e.Node.ContextMenuStrip = this.contextLibrary_bitmap;
			}
			else
			{
				libSel = e.Node;
			}
		}
		
		/*
		 * Context/Library/Bitmap/Set source bitmap...
		 */
		void SetSourceImageToolStripMenuItem1Click(object sender, EventArgs e)
		{
			SetSourceImageToolStripMenuItemClick(sender, e);
		}
		
		/*
		 * Context/Library/Clip/Add...
		 */
		void AddClipToolStripMenuItemClick(object sender, EventArgs e)
		{
			nc = new NewClip();
		}
		
		/*
		 * Context/Library/Clip/Edit
		 */
		void EditToolStripMenuItem1Click(object sender, EventArgs e)
		{
			libEdit = libSel;
			this.tcStage.Enabled = true;
			this.txtPropName.Text = libSel.Text;
			this.lblClipName.Text = Workspace.CLIP_NAME_NAME + libSel.Text;
			
			this.txtX.Text = ((Clip)libSel.Tag).r.X.ToString();
			this.txtY.Text = ((Clip)libSel.Tag).r.Y.ToString();
			this.txtW.Text = ((Clip)libSel.Tag).r.Width.ToString();
			this.txtH.Text = ((Clip)libSel.Tag).r.Height.ToString();
			
			PropertiesShow(true);
			
			this.picStage.Invalidate();
		}
		
		/*
		 * Cbo/Zoom
		 */
		void CboZoomSelectedIndexChanged(object sender, EventArgs e)
		{
			int zoom = int.Parse(this.cboZoom.Text.Trim('%').Trim());
			
			if (zoom < 100)
			{
				this.cboZoom.Text = "100%";
				return;
			}
			else if (zoom > 1000)
			{
				this.cboZoom.Text = "1000%";
				return;
			}
			
			Stage.zoom = zoom / 100;
			this.picStage.Invalidate();
		}

		/*
		 * Name changed
		 */
		void TxtPropNameTextChanged(object sender, EventArgs e)
		{
			libEdit.Text = this.txtPropName.Text;
			((Clip)libEdit.Tag).name = this.txtPropName.Text;
			this.lblClipName.Text = Workspace.CLIP_NAME_NAME + this.txtPropName.Text;
			
			this.picStage.Invalidate();
			this.treeLibrary.Invalidate();
		}
		
		/*
		 * X changed
		 */
		void TxtXTextChanged(object sender, EventArgs e)
		{
			int value = Utils.String2Int(this.txtX.Text);
			this.txtX.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.X = value;
			this.picStage.Invalidate();
		}
		
		/*
		 * Y changed
		 */
		void TxtYTextChanged(object sender, EventArgs e)
		{
			int value = Utils.String2Int(this.txtY.Text);
			this.txtY.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.Y = value;
			this.picStage.Invalidate();
		}
		
		/*
		 * W changed
		 */
		void TxtWTextChanged(object sender, EventArgs e)
		{
			int value = Utils.String2Int(this.txtW.Text);
			this.txtW.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.Width = value;
			this.picStage.Invalidate();
		}
		
		/*
		 * H changed
		 */
		void TxtHTextChanged(object sender, EventArgs e)
		{
			int value = Utils.String2Int(this.txtH.Text);
			this.txtH.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.Height = value;
			this.picStage.Invalidate();
		}
	}
}
